package com.dctp.ems.controller;

import com.dctp.common.controller.BaseController;
import com.dctp.common.utils.DateUtil;
import com.dctp.common.vo.JsonResult;
import com.jfinal.aop.Before;
import com.jfinal.core.Path;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

import java.util.*;
import java.util.stream.Collectors;

/**
 * EMS 菜单接口
 *
 * basePath : /menu
 */
@Path("/menu")
public class EmsMenuController extends BaseController {

    /* ────────────── 1. 列表 GET /menu/list ────────────── */
    public void list() {
        List<Record> rows = Db.find("SELECT * FROM card_enterprise_menu ORDER BY id ASC");
        List<Kv> out = rows.stream().map(this::snakeToCamel).collect(Collectors.toList());
        renderJson(JsonResult.successWithData(out));
    }

    /* ────────────── 2. 树形 GET /menu/tree ────────────── */
    public void tree() {
        List<Record> rows = Db.find("SELECT * FROM card_enterprise_menu ORDER BY id ASC");
        List<Kv> list = rows.stream().map(this::snakeToCamel).collect(Collectors.toList());
        renderJson(JsonResult.successWithData(buildTree(list, 0)));
    }

    /* ────────────── 3. 新增 POST /menu/add ────────────── */
    @Before(Tx.class)
    public void add() {
        Record body = jsonBody();
        if (StrKit.isBlank(body.getStr("title"))) {
            renderJson(JsonResult.failWithMessage("title 不能为空"));
            return;
        }

        Record rec = camelToSnake(body)
            .set("create_time", DateUtil.now());

        if (!Db.save("card_enterprise_menu", rec))
            throw new RuntimeException("新增菜单失败");

        Long menuId = rec.getLong("id");
        Long superId = Db.queryLong(
            "SELECT id FROM card_enterprise_role WHERE role='super_admin' LIMIT 1");
        if (superId != null) {
            Db.save("card_enterprise_role_menu",
                new Record().set("role_id", superId).set("menu_id", menuId));
        }
        renderJson(JsonResult.success());
    }

    /* ────────────── 4. 更新 POST /menu/update/:id ────────────── */
    @Before(Tx.class)
    public void update() {
        Long id = getParaToLong(0);
        if (id == null) { renderJson(JsonResult.failWithMessage("参数缺失")); return; }

        Record body = camelToSnake(jsonBody())
                .set("id", id)
                .set("update_time", DateUtil.now());

        if (!Db.update("card_enterprise_menu", body))
            throw new RuntimeException("更新菜单失败");

        renderJson(JsonResult.success());
    }

    /* ────────────── 5. 删除 POST /menu/delete/:id ────────────── */
    @Before(Tx.class)
    public void delete() {
        Long id = getParaToLong(0);
        if (id == null) { renderJson(JsonResult.failWithMessage("参数缺失")); return; }

        Db.update("DELETE FROM card_enterprise_role_menu WHERE menu_id=?", id);
        int n = Db.update("DELETE FROM card_enterprise_menu WHERE id=?", id);
        if (n == 0) throw new RuntimeException("菜单不存在或已删除");
        renderJson(JsonResult.success());
    }

    /* ────────────── snake → camel ────────────── */

    private static final Set<String> IGNORE_COLS =
        Set.of("create_time", "update_time");

    private static final Set<String> BOOL_COLS =
        Set.of("frame_loading", "keep_alive", "hidden_tag",
               "fixed_tag", "show_link", "show_parent");

    private Kv snakeToCamel(Record rec) {
        Kv kv = Kv.create();
        for (String col : rec.getColumnNames()) {
            if (IGNORE_COLS.contains(col)) continue;
            Object val = rec.get(col);
            if (BOOL_COLS.contains(col) && val != null) {
                val = !"0".equals(val.toString());
            }
            kv.set(toCamel(col), val);
        }
        return kv;
    }

    private String toCamel(String snake) {
        StringBuilder sb = new StringBuilder();
        boolean up = false;
        for (char c : snake.toCharArray()) {
            if (c == '_') { up = true; continue; }
            sb.append(up ? Character.toUpperCase(c) : c);
            up = false;
        }
        return sb.toString();
    }

    /* ────────────── camel → snake (自动遍历) ────────────── */

    private Record camelToSnake(Record body) {
        Record out = new Record();
        for (String camelKey : body.getColumnNames()) {
            Object val = body.get(camelKey);
            if (val != null) {
                out.set(toSnake(camelKey), val);
            }
        }
        return out;
    }

    private String toSnake(String camel) {
        StringBuilder sb = new StringBuilder();
        for (char c : camel.toCharArray()) {
            if (Character.isUpperCase(c)) {
                sb.append('_').append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /* ────────────── 递归组树 ────────────── */

    private List<Kv> buildTree(List<Kv> list, int pid) {
        List<Kv> out = new ArrayList<>();
        for (Kv k : list) {
            int parentId = k.getInt("parentId", 0);
            if (parentId == pid) {
                List<Kv> children = buildTree(list, k.getInt("id"));
                if (!children.isEmpty()) k.set("children", children);
                out.add(k);
            }
        }
        return out;
    }
}
